package game

import (
	"fmt"
	"math"
	"server/GoUtil"
	"server/MergeConst"
	"server/db"
	"server/msg"
	"strconv"
	"strings"
	"time"

	"google.golang.org/protobuf/proto"
)

type PlayerLimitDataModule interface {
	ResLimitData(player *Player)
	ResAddLimitTime(buf []byte)
}

type PlayerLimitData struct {
	*PlayerData
	MsqlStruck db.SqlLimitDataStruct
	Type       int32
	MActType   int
	MActiveID  int32
	Data       msg.ResLimitData
	MDbName    string
}

func (p *PlayerLimitData) OpenNewLimitEvent(args []interface{}) {
	if p.MActType != args[3].(int) {
		return
	}
	// if p.Data.ID == 5 {
	// 	if p.MsqlStruck.ParamStr != "" {
	// 		strr := strings.Split(p.MsqlStruck.ParamStr, ";")
	// 		if int32(time.Now().Unix()) > p.MsqlStruck.EndLimitTime {
	// 			p.MsqlStruck.ParamStr = strr[0] + ";" + "0" + ";" + "1"
	// 		} else {
	// 			if len(strr) == 2 {
	// 				p.MsqlStruck.ParamStr = strr[0] + ";" + strr[1] + ";" + "2"
	// 			} else {
	// 				cd, _ := strconv.Atoi(strr[2])
	// 				cd = cd + 1
	// 				p.MsqlStruck.ParamStr = strr[0] + ";" + strr[1] + ";" + strconv.Itoa(cd)
	// 			}
	// 		}
	// 	} else {
	// 		p.MsqlStruck.ParamStr = "1" + ";" + "0" + ";" + "1"
	// 	}
	// }
	// p.Data.ParamStr = p.MsqlStruck.ParamStr

	p.HandleNewLimitTime()
	res := &msg.NotifyLimitData{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())
	res.ParamStr = p.MsqlStruck.ParamStr
	if p.Data.ID == 2 {
		p.M_Player.GetIFGameData("PlayerEmitDetaliData").(*PlayerEmitDetaliData).ClearAllEmitCD()

	}
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "NotifyLimitData", data)
	p.SaveDataFromDB("")
}

func (p *PlayerLimitData) HandleNewLimitTime() {
	LEP := G_GameLogicPtr.MLimiteEventManager.GetLimitDataStatus(int(p.MActType))
	if LEP != nil {
		CurTime := int32(time.Now().Unix())
		if p.Data.ID != 9 {
			if p.MsqlStruck.AddEndTime < LEP.StartTime { //没有添加活动时间

				if p.MsqlStruck.EndLimitTime < CurTime {
					p.MsqlStruck.EndLimitTime = CurTime + LEP.AddTimes
					p.MsqlStruck.StartLimitTime = CurTime
					p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
				} else {
					p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + LEP.AddTimes
					p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
				}
				p.MsqlStruck.AddEndTime = LEP.StartTime
				if p.Data.ID == 8 {
					p.MsqlStruck.ParamStr = "0" + ";" + "0"
					p.Data.ParamStr = p.MsqlStruck.ParamStr
				}
				if p.Data.ID == 10 {
					p.MsqlStruck.ParamStr = ""
					p.Data.ParamStr = p.MsqlStruck.ParamStr
				}
				if p.Data.ID == 5 {
					if p.MsqlStruck.ParamStr != "" {
						strr := strings.Split(p.MsqlStruck.ParamStr, ";")
						if int32(time.Now().Unix()) > p.MsqlStruck.EndLimitTime {
							p.MsqlStruck.ParamStr = strr[0] + ";" + "0" + ";" + "1"
						} else {
							if len(strr) == 2 {
								p.MsqlStruck.ParamStr = strr[0] + ";" + strr[1] + ";" + "2"
							} else {
								cd, _ := strconv.Atoi(strr[2])
								cd = cd + 1
								p.MsqlStruck.ParamStr = strr[0] + ";" + strr[1] + ";" + strconv.Itoa(cd)
							}
						}
					} else {
						p.MsqlStruck.ParamStr = "1" + ";" + "0" + ";" + "1"
					}
					p.Data.ParamStr = p.MsqlStruck.ParamStr
				}

			} else {
				p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
			}
		} else {
			if p.MsqlStruck.AddEndTime < LEP.EndTime { //没有添加活动时间
				if p.MsqlStruck.EndLimitTime > LEP.StartTime {
					Delta := p.MsqlStruck.EndLimitTime - LEP.StartTime
					p.MsqlStruck.EndLimitTime = Delta + LEP.EndTime
					p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
				} else {
					p.MsqlStruck.StartLimitTime = LEP.StartTime
					p.MsqlStruck.EndLimitTime = LEP.EndTime
					p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
				}
				p.MsqlStruck.AddEndTime = LEP.EndTime
				ParamStr := fmt.Sprintf("%d;%d;%d", G_GameLogicPtr.M_SvrGlobal.Limit4Card, G_GameLogicPtr.M_SvrGlobal.Limit5Card, 0)
				p.MsqlStruck.ParamStr = ParamStr
				p.Data.ParamStr = p.MsqlStruck.ParamStr

			} else {
				p.MsqlStruck.StartLimitTime = LEP.StartTime
				p.MsqlStruck.EndLimitTime = LEP.EndTime
				p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
			}
		}

	}
}

func (p *PlayerLimitData) ClearData() bool {
	GoUtil.RemoveEvent(MergeConst.OpenNewLimitEvent, p.OpenNewLimitEvent, p)
	return true
}
func (p *PlayerLimitData) Reconnect(b bool) {
	GoUtil.RemoveEvent(MergeConst.OpenNewLimitEvent, p.OpenNewLimitEvent, p)
	GoUtil.RegisterEvent(MergeConst.OpenNewLimitEvent, p.OpenNewLimitEvent, p)

	p.HandleNewLimitTime()
}

func (p *PlayerLimitData) ResLimitData(player *Player) {

}

func (p *PlayerLimitData) ResAddLimitTime(buf []byte) {

}

func (p *PlayerLimitData) SaveDataFromDB(Key interface{}) bool {

	if p.IsHaveDataDb {
		db.FormatAllMemUpdateDb(&p.MsqlStruck, p.MDbName, "dwUin")
	} else {
		db.FormatAllMemInsertDb(&p.MsqlStruck, p.MDbName)
	}
	p.IsHaveDataDb = true
	return true
}

// ///////
type PlayerHighRollerData struct {
	*PlayerLimitData
}

func (p *PlayerHighRollerData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_High_Roller WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 4
	p.Data.ID = 4
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime

	p.Reconnect(false)
	return true
}

func (p *PlayerHighRollerData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerHighRollerData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerHighRollerData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerHighRollerData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerHighRollerData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerHighRollerData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerChestRainData struct {
	*PlayerLimitData
}

func (p *PlayerChestRainData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Chest_Rain WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 1
	p.Data.ID = 1
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime

	p.Reconnect(false)
	return true
}

func (p *PlayerChestRainData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerChestRainData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
	p.M_Player.GetIFGameData("PlayerEmitDetaliData").(*PlayerEmitDetaliData).ClearAllEmitCD()
}

func (p *PlayerChestRainData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerChestRainData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerChestRainData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerChestRainData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerSuperEmiterData struct {
	*PlayerLimitData
}

func (p *PlayerSuperEmiterData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Super_Emiter WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 2
	p.Data.ID = 2
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime

	p.Reconnect(false)
	return true
}

func (p *PlayerSuperEmiterData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerSuperEmiterData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerSuperEmiterData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerSuperEmiterData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerSuperEmiterData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerSuperEmiterData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerStarRainData struct {
	*PlayerLimitData
}

func (p *PlayerStarRainData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Star_Rain WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 3
	p.Data.ID = 3
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime

	p.Reconnect(false)
	return true
}

func (p *PlayerStarRainData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerStarRainData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerStarRainData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerStarRainData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerStarRainData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerStarRainData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerSuperOrderData struct {
	*PlayerLimitData
}

func (p *PlayerSuperOrderData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Super_Order WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 5
	p.Data.ID = 5
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime

	if p.MsqlStruck.ParamStr != "" {
		strr := strings.Split(p.MsqlStruck.ParamStr, ";")
		// cd, _ := strconv.Atoi(strr[1])
		if int32(time.Now().Unix()) > p.MsqlStruck.EndLimitTime {
			p.MsqlStruck.ParamStr = strr[0] + ";" + "0" + ";" + "0"
		} else {
			if len(strr) == 2 {
				p.MsqlStruck.ParamStr = strr[0] + ";" + strr[1] + ";" + "1"
			} else {

			}
		}
	} else {

	}
	p.Data.ParamStr = p.MsqlStruck.ParamStr

	p.Reconnect(false)
	return true
}

func (p *PlayerSuperOrderData) AddNewLimitTime(dur int32) {

	if p.MsqlStruck.ParamStr != "" {
		strr := strings.Split(p.MsqlStruck.ParamStr, ";")
		if int32(time.Now().Unix()) > p.MsqlStruck.EndLimitTime {
			p.MsqlStruck.ParamStr = strr[0] + ";" + "0" + ";" + "1"
		} else {
			if len(strr) == 2 {
				p.MsqlStruck.ParamStr = strr[0] + ";" + strr[1] + ";" + "2"
			} else {
				cd, _ := strconv.Atoi(strr[2])
				cd = cd + 1
				p.MsqlStruck.ParamStr = strr[0] + ";" + strr[1] + ";" + strconv.Itoa(cd)
			}
		}
	} else {
		p.MsqlStruck.ParamStr = "1" + ";" + "0" + ";" + "1"
	}
	p.Data.ParamStr = p.MsqlStruck.ParamStr

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())
	res.ParamStr = p.MsqlStruck.ParamStr

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerSuperOrderData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}
func (p *PlayerSuperOrderData) ReqEndSuperOrder(buf []byte) {
	req := &msg.ReqEndSuperOrder{}
	res := &msg.ResEndSuperOrder{}
	proto.Unmarshal(buf, req)

	p.MsqlStruck.ParamStr = "1" + ";" + "0" + ";" + "0"
	p.MsqlStruck.EndLimitTime = int32(time.Now().Unix())
	p.Data.ParamStr = p.MsqlStruck.ParamStr
	res.ParamStr = p.MsqlStruck.ParamStr
	res.EndLimitTime = p.MsqlStruck.EndLimitTime
	p.SaveDataFromDB("")

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResEndSuperOrder", data)
}

func (p *PlayerSuperOrderData) ResGenSuperOrder(buf []byte) {
	req := &msg.ReqGenSuperOrder{}
	res := &msg.ResGenSuperOrder{}
	proto.Unmarshal(buf, req)
	res.GenOrderTime = int32(time.Now().Unix())

	// if res.GenOrderTime+600 > p.Data.EndLimitTime {
	// 	res.GenOrderTime = p.Data.EndLimitTime - 600
	// }
	strr := strings.Split(p.MsqlStruck.ParamStr, ";")

	cd, _ := strconv.Atoi(strr[2])
	if cd == 0 {
		return
	}
	cd = cd - 1

	// p.MsqlStruck.ParamStr = ""
	strr1 := []string{}
	for i := 0; i < len(req.IdList); i++ {
		strr1 = append(strr1, fmt.Sprintf("%d", req.IdList[i]))
	}

	p.MsqlStruck.ParamStr = strings.Join(strr1, ",") + ";" + fmt.Sprintf("%d", res.GenOrderTime) + ";" + strconv.Itoa(cd)
	res.ParamStr = p.MsqlStruck.ParamStr
	p.Data.ParamStr = p.MsqlStruck.ParamStr
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResGenSuperOrder", data)

	p.SaveDataFromDB("")
}

func (p *PlayerSuperOrderData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerSuperOrderData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerSuperOrderData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerSuperOrderData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerSceneSprintData struct {
	*PlayerLimitData
}

func (p *PlayerSceneSprintData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Star_Rain WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 6
	p.Data.ID = 6
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime

	p.Reconnect(false)
	return true
}

func (p *PlayerSceneSprintData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerSceneSprintData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerSceneSprintData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerSceneSprintData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerSceneSprintData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerSceneSprintData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerCardFestivalData struct {
	*PlayerLimitData
}

func (p *PlayerCardFestivalData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Star_Rain WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 7
	p.Data.ID = 7
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime

	p.Reconnect(false)
	return true
}

func (p *PlayerCardFestivalData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerCardFestivalData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerCardFestivalData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerCardFestivalData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerCardFestivalData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerCardFestivalData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerCardSwapData struct {
	*PlayerLimitData
}

func (p *PlayerCardSwapData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Star_Rain WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 9
	p.Data.ID = 9
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	p.Data.ParamStr = p.MsqlStruck.ParamStr
	p.Reconnect(false)
	return true
}

func (p *PlayerCardSwapData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerCardSwapData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerCardSwapData) IsLimitCardPeriod() bool {
	CurTime := int32(time.Now().Unix())
	if CurTime >= p.Data.EndLimitTime || p.Data.ParamStr == "" {
		return false
	}
	return true
}

func (p *PlayerCardSwapData) GetLimitCardCnt() int {

	units := strings.Split(p.Data.ParamStr, ";")
	cnt, _ := strconv.Atoi(units[2])

	return cnt
}
func (p *PlayerCardSwapData) IsLimitCardSwapCard(cardId int) bool {
	CurTime := int32(time.Now().Unix())
	if CurTime > p.Data.EndLimitTime {
		return false
	}
	if p.Data.ParamStr == "" {
		return false
	}
	units := strings.Split(p.Data.ParamStr, ";")
	id1, _ := strconv.Atoi(units[0])
	id2, _ := strconv.Atoi(units[1])
	if id1 == cardId || id2 == cardId {
		return true
	}
	return false
}

func (p *PlayerCardSwapData) AddGoldCardExchange() {
	units := strings.Split(p.Data.ParamStr, ";")
	cnt, _ := strconv.Atoi(units[2])
	cnt = cnt + 1
	units[2] = fmt.Sprintf("%d", cnt)
	p.MsqlStruck.ParamStr = strings.Join(units, ";")
	p.Data.ParamStr = p.MsqlStruck.ParamStr
	p.NotifyLimitCardSwapData()
}

func (p *PlayerCardSwapData) NotifyLimitCardSwapData() {
	notify := &msg.NotifyLimitCardSwapData{}
	units := strings.Split(p.Data.ParamStr, ";")
	cnt, _ := strconv.Atoi(units[2])

	notify.CurTime = int32(cnt)
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(notify)
	G_getGameLogic().PackResInfo(agent, "NotifyLimitCardSwapData", data)
}

func (p *PlayerCardSwapData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerCardSwapData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerCardSwapData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerCardSwapData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerPetRobberData struct {
	*PlayerLimitData
}

func (p *PlayerPetRobberData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Star_Rain WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 10
	p.Data.ID = 10
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	p.Data.ParamStr = p.MsqlStruck.ParamStr
	p.Reconnect(false)
	return true
}

func (p *PlayerPetRobberData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
		p.MsqlStruck.ParamStr = ""
		p.Data.ParamStr = ""
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerPetRobberData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerPetRobberData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerPetRobberData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerPetRobberData) NotifyRenewTagThief() {
	notify := &msg.NotifyRenewTagThief{}
	notify.ParamStr = p.Data.ParamStr

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(notify)
	G_getGameLogic().PackResInfo(agent, "notify", data)
}

func (p *PlayerPetRobberData) ReqTagThief(buf []byte) {

	req := &msg.ReqTagThief{}
	res := &msg.ResTagThief{}
	proto.Unmarshal(buf, req)

	HomeInterActs := p.M_Player.GetGameData("PlayerPetHomeData").(*PlayerPetHomeData).GetHomeInterActST()
	FriendInfos := p.M_Player.GetGameData("PlayerFriendData").(*PlayerFriendData).Data.FriendInfos

	mergeSet := []int32{}
	for i := 0; i < len(HomeInterActs); i++ {
		mergeSet = append(mergeSet, HomeInterActs[i].DwUin)
	}

	isExsit := func(friendId int32) bool {
		for i := 0; i < len(HomeInterActs); i++ {
			if HomeInterActs[i].DwUin == friendId {
				return true
			}
		}
		return false
	}

	for i := 0; i < len(FriendInfos); i++ {
		if !isExsit(FriendInfos[i].DwUin) {
			mergeSet = append(mergeSet, FriendInfos[i].DwUin)
		}
	}

	if p.Data.ParamStr == "" {
		if len(mergeSet) > 0 {
			cnt := int(math.Min(float64(len(mergeSet)), 10))
			str := []string{}

			for i := 0; i < cnt; i++ {
				str = append(str, strconv.Itoa(int(mergeSet[i])))
			}
			p.Data.ParamStr = strings.Join(str, ",") + ";"
			p.MsqlStruck.ParamStr = p.Data.ParamStr
		}

	} else {
		units := strings.Split(p.Data.ParamStr, ";")
		if units[1] != "" {
			ids := strings.Split(units[1], ",")
			for i := 0; i < len(ids); i++ {
				id, _ := strconv.Atoi(ids[i])
				ExcludeId := int32(id)
				tempRet := []int32{}
				for m := 0; m < len(mergeSet); m++ {
					if mergeSet[m] != ExcludeId {
						tempRet = append(tempRet, mergeSet[m])
					}
				}
				mergeSet = tempRet
			}
		}
		if len(mergeSet) > 0 {
			cnt := int(math.Min(float64(len(mergeSet)), 10))
			str := []string{}

			for i := 0; i < cnt; i++ {
				str = append(str, strconv.Itoa(int(mergeSet[i])))
			}
			units[0] = strings.Join(str, ",")
			p.Data.ParamStr = strings.Join(units, ";")
			p.MsqlStruck.ParamStr = p.Data.ParamStr
		} else {
			units[0] = ""
			p.Data.ParamStr = strings.Join(units, ";")
			p.MsqlStruck.ParamStr = p.Data.ParamStr
		}
	}
	res.ParamStr = p.Data.ParamStr
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResTagThief", data)
	p.SaveDataFromDB("")
}

func (p *PlayerPetRobberData) IsInPetRobberLimit() bool {
	CurTime := time.Now().Unix()
	if CurTime < int64(p.MsqlStruck.EndLimitTime) && CurTime > int64(p.MsqlStruck.StartLimitTime) {
		return true
	}
	return false
}

func (p *PlayerPetRobberData) RemoveTagByPlayerId(playerId int32) {

	if p.Data.ParamStr == "" {
		return
	} else {
		units := strings.Split(p.Data.ParamStr, ";")
		if units[0] == "" {
			return
		} else {
			strr := strings.Split(units[0], ",")
			ids := []string{}
			for i := 0; i < len(strr); i++ {
				id, _ := strconv.Atoi(strr[i])
				if id != int(playerId) {
					ids = append(ids, strconv.Itoa(id))
				} else {
					if units[1] != "" {
						units[1] = units[1] + "," + strconv.Itoa(id)
					} else {
						units[1] = strconv.Itoa(id)
					}
				}
			}
			units[0] = strings.Join(ids, ",")
			p.Data.ParamStr = strings.Join(units, ";")
			p.MsqlStruck.ParamStr = p.Data.ParamStr
			p.NotifyRenewTagThief()
			p.SaveDataFromDB("")
		}
	}

}

func (p *PlayerPetRobberData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerPetRobberData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}

//////////

type PlayerDoubleHitData struct {
	*PlayerLimitData
}

func (p *PlayerDoubleHitData) LoadDataFromDB(dwUin interface{}) bool {

	// sqlStr := "SELECT * FROM t_Limit_Star_Rain WHERE dwUin = ?"
	sqlStr := "SELECT * FROM " + p.MDbName + " WHERE dwUin = ?"
	p.MsqlStruck.DwUin = dwUin.(int32)
	if err := db.SqlDb.Get(&p.MsqlStruck, sqlStr, dwUin.(int32)); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		p.IsHaveDataDb = false
	} else {
		p.IsHaveDataDb = true
	}
	p.MActType = 8
	p.Data.ID = 8
	p.Data.StartLimitTime = p.MsqlStruck.StartLimitTime
	p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	p.Data.ParamStr = p.MsqlStruck.ParamStr

	p.Reconnect(false)
	return true
}

func (p *PlayerDoubleHitData) AddNewLimitTime(dur int32) {

	CurSvrTime := int32(time.Now().Unix())
	if CurSvrTime > p.MsqlStruck.EndLimitTime {
		p.MsqlStruck.EndLimitTime = CurSvrTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
		p.MsqlStruck.ParamStr = "0" + ";" + "0"
		p.Data.ParamStr = p.MsqlStruck.ParamStr
	} else {
		p.MsqlStruck.EndLimitTime = p.MsqlStruck.EndLimitTime + dur
		p.Data.EndLimitTime = p.MsqlStruck.EndLimitTime
	}
	res := &msg.ResAddLimitTime{}
	res.EndLimitTime = p.Data.EndLimitTime
	res.ID = p.Data.ID
	res.ParamStr = p.Data.ParamStr
	res.CurSvrTime = int32(time.Now().Unix())

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResAddLimitTime", data)
	p.SaveDataFromDB("")
}

func (p *PlayerDoubleHitData) ResAddLimitTime(buf []byte) {
	req := &msg.ReqAddLimitTime{}
	proto.Unmarshal(buf, req)
	p.AddNewLimitTime(req.AddLimitTime)
}

func (p *PlayerDoubleHitData) Reconnect(b bool) {

	p.PlayerLimitData.Reconnect(b)
}

func (p *PlayerDoubleHitData) ReqCompleteDoubleHit(buf []byte) {
	req := &msg.ReqCompleteDoubleHit{}
	res := &msg.ResCompleteDoubleHit{}
	proto.Unmarshal(buf, req)

	curTime := int32(time.Now().Unix())
	if p.MsqlStruck.ParamStr != "" {
		units := strings.Split(p.MsqlStruck.ParamStr, ";")
		curCnt, _ := strconv.Atoi(units[0])
		curCnt = curCnt + 1
		save := fmt.Sprintf("%d;%d", curCnt, curTime)
		p.MsqlStruck.ParamStr = save
		p.Data.ParamStr = save
		p.SaveDataFromDB("")

		res.CurCnt = int32(curCnt)
	} else {
		curCnt := 1
		save := fmt.Sprintf("%d;%d", curCnt, curTime)
		p.MsqlStruck.ParamStr = save
		p.Data.ParamStr = save
		p.SaveDataFromDB("")

		res.CurCnt = int32(curCnt)
	}
	res.CompleteTime = curTime

	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(agent, "ResCompleteDoubleHit", data)
}

func (p *PlayerDoubleHitData) ResLimitData(player *Player) {
	if player != p.M_Player {
		return
	}
	p.Data.CurSvrTime = int32(time.Now().Unix())
	agent := p.GetPlayer().GetAgentByPlayer()
	data, _ := proto.Marshal(&p.Data)
	G_getGameLogic().PackResInfo(agent, "ResLimitData", data)
}

func (p *PlayerDoubleHitData) SaveDataFromDB(Key interface{}) bool {
	p.PlayerLimitData.SaveDataFromDB("")
	return true
}

func (p *PlayerDoubleHitData) ClearData() bool {
	p.SaveDataFromDB("")
	p.PlayerLimitData.ClearData()

	return true
}
